/**
 * 
 */
package com.tiduyun.data.exchange.util.http;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;

import org.apache.http.HttpHost;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.protocol.HttpContext;

/**
 * @author wuzheng@tiduyun.com
 *
 */
public class SocksProxyConnectionSocketFactory extends PlainConnectionSocketFactory {

    /**
     * @see org.apache.http.conn.socket.PlainConnectionSocketFactory#createSocket(org.apache.http.protocol.HttpContext)
     */
    @Override
    public Socket createSocket(HttpContext context) throws IOException {
        Proxy proxy = (Proxy) context.getAttribute("proxy");
        if (isSocksProxy(proxy)) {
            return new Socket(proxy);
        } else {
            return super.createSocket(context);
        }
    }

    private boolean isSocksProxy(Proxy proxy) {
        return proxy != null && Proxy.Type.SOCKS.equals(proxy.type());
    }

    /**
     * @see org.apache.http.conn.socket.PlainConnectionSocketFactory#connectSocket(int,
     *      java.net.Socket, org.apache.http.HttpHost,
     *      java.net.InetSocketAddress, java.net.InetSocketAddress,
     *      org.apache.http.protocol.HttpContext)
     */
    @Override
    public Socket connectSocket(int connectTimeout, Socket socket, HttpHost host, InetSocketAddress remoteAddress,
            InetSocketAddress localAddress, HttpContext context) throws IOException {
        Proxy proxy = (Proxy) context.getAttribute("proxy");
        if (isSocksProxy(proxy)) { // make proxy server to resolve host in url
            remoteAddress = InetSocketAddress.createUnresolved(host.getHostName(), remoteAddress.getPort());
        }
        return super.connectSocket(connectTimeout, socket, host, remoteAddress, localAddress, context);
    }
}
